package com.lcf.framework.utils;

import com.lcf.framework.exception.SysException;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

@Slf4j
public class RsaUtils {

    /**
     * RSA公钥加密（需传入公钥）
     */
    public static String encrypt(String plaintext, String publicKey) {
        try {
            if (!isPublicKeyValid(publicKey)) {
                throw new SysException("无效的公钥格式");
            }

            byte[] decodedKey = Base64.getUrlDecoder().decode(publicKey);
            PublicKey pubKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decodedKey));

            Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
            cipher.init(Cipher.ENCRYPT_MODE, pubKey);
            byte[] encryptedBytes = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8));

            return Base64.getUrlEncoder().withoutPadding().encodeToString(encryptedBytes);
        } catch (InvalidKeyException e) {
            log.error("无效的公钥: {}", publicKey, e);
            throw new SysException("公钥不合法");
        } catch (Exception e) {
            log.error("加密失败", e);
            throw new SysException("加密过程中发生错误");
        }
    }

    /**
     * RSA私钥解密（需传入私钥）
     */
    public static String decrypt(String ciphertext, String privateKey) {
        try {
            if (!isPrivateKeyValid(privateKey)) {
                throw new SysException("无效的私钥格式");
            }

            byte[] decodedKey = Base64.getUrlDecoder().decode(privateKey);
            PrivateKey priKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decodedKey));

            Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
            cipher.init(Cipher.DECRYPT_MODE, priKey);
            byte[] decryptedBytes = cipher.doFinal(Base64.getUrlDecoder().decode(ciphertext));

            return new String(decryptedBytes, StandardCharsets.UTF_8);
        } catch (InvalidKeyException e) {
            log.error("无效的私钥: {}", privateKey, e);
            throw new SysException("私钥不合法");
        } catch (Exception e) {
            log.error("解密失败", e);
            throw new SysException("解密过程中发生错误");
        }
    }

    /**
     * 生成 RSA 密钥对（2048 位）
     */
    public static RsaPair generateKeyPair() {
        try {
            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
            keyPairGen.initialize(2048, new SecureRandom());
            KeyPair keyPair = keyPairGen.generateKeyPair();

            String publicKey = Base64.getUrlEncoder().withoutPadding().encodeToString(keyPair.getPublic().getEncoded());
            String privateKey = Base64.getUrlEncoder().withoutPadding().encodeToString(keyPair.getPrivate().getEncoded());

            return new RsaPair(publicKey, privateKey);
        } catch (NoSuchAlgorithmException e) {
            throw new SysException(e);
        }
    }

    @Data
    @NoArgsConstructor
    public static class RsaPair {
        private String publicKey;
        private String privateKey;

        public RsaPair(String publicKey, String privateKey) {
            this.publicKey = publicKey;
            this.privateKey = privateKey;
        }
    }

    public static boolean isPublicKeyValid(String publicKey) {
        try {
            byte[] decoded = Base64.getUrlDecoder().decode(publicKey);
            KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public static boolean isPrivateKeyValid(String privateKey) {
        try {
            byte[] decoded = Base64.getUrlDecoder().decode(privateKey);
            KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
            return true;
        } catch (Exception e) {
            return false;
        }
    }


    // 测试代码
    public static void main(String[] args) {
        RsaPair pair = generateKeyPair();
        String originalText = "URL变体修改的Base64";

        String encrypted = encrypt(originalText, pair.getPublicKey());
        System.out.println("加密结果: " + encrypted);

        String decrypted = decrypt(encrypted, pair.getPrivateKey());
        System.out.println("解密结果: " + decrypted);
    }
}
